package com.insight.modules.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuanqiao.insight.common.base.BaseMap;
import com.yuanqiao.insight.common.constant.GlobalConstants;
import lombok.extern.slf4j.Slf4j;
import com.insight.common.constant.CacheConstant;
import com.insight.modules.system.entity.SysGatewayRoute;
import com.insight.modules.system.mapper.SysGatewayRouteMapper;
import com.insight.modules.system.service.ISysGatewayRouteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @Description: gateway路由管理
 * @Author: jeecg-boot
 * @Date: 2020-05-26
 * @Version: V1.0
 */
@Service
@Slf4j
public class SysGatewayRouteServiceImpl extends ServiceImpl<SysGatewayRouteMapper, SysGatewayRoute> implements ISysGatewayRouteService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 将所有状态为启用（1）的网关路由数据加载到Redis缓存
     * @param key Redis中存储的key
     */
    @Override
    public void addRoute2Redis(String key) {
        // 查询所有启用的路由配置
        List<SysGatewayRoute> ls = this.list(new LambdaQueryWrapper<SysGatewayRoute>().eq(SysGatewayRoute::getStatus, 1));
        // 将路由集合序列化为JSON字符串存入Redis
        redisTemplate.opsForValue().set(key, JSON.toJSONString(ls));
    }

    /**
     * 根据ID删除路由，并刷新网关路由缓存
     * @param id 路由ID
     */
    @Override
    public void deleteById(String id) {
        this.removeById(id);
        // 删除后刷新路由缓存和通知网关刷新
        this.resreshRouter();
    }

    /**
     * 根据前端传入的JSON更新或者新增路由信息，并刷新缓存
     * @param json 路由信息JSON对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAll(JSONObject json) {
        log.info("--gateway 路由配置修改--");

        json = json.getJSONObject("router");
        String id = json.getString("id");
        SysGatewayRoute route = getById(id);
        if (ObjectUtil.isEmpty(route)) {
            route = new SysGatewayRoute();
        }
        route.setRouterId(json.getString("routerId"));
        route.setName(json.getString("name"));
        route.setPredicates(json.getString("predicates"));
        String filters = json.getString("filters");
        if (ObjectUtil.isEmpty(filters)) {
            filters = "[]";
        }
        route.setFilters(filters);
        route.setUri(json.getString("uri"));
        if (json.get("status") == null) {
            route.setStatus(1);
        } else {
            route.setStatus(json.getInteger("status"));
        }
        this.saveOrUpdate(route);
        resreshRouter();

    }

    /**
     * 刷新Redis中的路由缓存并通过Redis消息通知网关刷新路由配置
     */
    private void resreshRouter() {
        // 将当前启用的路由配置更新到Redis缓存
        addRoute2Redis(CacheConstant.GATEWAY_ROUTES);
        BaseMap params = new BaseMap();
        // 设置刷新处理器名称
        params.put(GlobalConstants.HANDLER_NAME, "loderRouderHandler");
        // 发送刷新通知到指定Redis频道，触发网关刷新路由
        redisTemplate.convertAndSend(GlobalConstants.REDIS_TOPIC_NAME, params);
    }

    /**
     * 清空Redis中网关路由缓存数据
     */
    @Override
    public void clearRedis() {
        redisTemplate.opsForValue().set(CacheConstant.GATEWAY_ROUTES, null);
    }
}

